//for timer apt: union sigval, timer_t...
#include <signal.h> 
#include <time.h>

#include <stdio.h> //perror
#include <stdlib.h> //exit
#include <string.h> //memset
#include <unistd.h> //sleep


void thread_route(union sigval v) { 
    printf("read as integer:%d\n", v.sival_int); 
    printf("read as pointer:%p\n", v.sival_ptr); 
}

 
void sig_handler(int signo)  { 
    printf("notify signal: %d\n", signo); 
} 

int main(int argc, char *argv[]) {
    /*** notify by thread ***/
    struct sigevent evp1;
    memset(&evp1, 0, sizeof(struct sigevent));
    evp1.sigev_value.sival_ptr = NULL;
    evp1.sigev_notify = SIGEV_THREAD;                //线程通知的方式，派驻新线程 
    evp1.sigev_notify_function = thread_route;       //线程函数地址
    
    timer_t timer1=0;
    if (timer_create(CLOCK_REALTIME, &evp1, &timer1) == -1) {   
        perror("fail to timer_create"); 
        exit(-1); 
    }

    struct itimerspec it1; 
    /*第一次间隔it.it_value这么长,以后每次都是it.it_interval这么长, 就是说
     *it.it_value变0的时候会>装载it.it_interval的值。如果it_inverval为0则不重复
     */
    it1.it_interval.tv_sec = 1;  // 回调函数执行频率为1s运行1次
    it1.it_interval.tv_nsec = 0; //必须初始化
    it1.it_value.tv_sec = 0;     // 倒计时3秒开始调用回调函数
    it1.it_value.tv_nsec = 800000000; 
 
    if (timer_settime(timer1, 0, &it1, NULL) == -1) {   
        perror("fail to timer_settime"); 
        exit(-1); 
    }   
 
    /*** notify by signal ***/
    struct sigevent evp2;
    memset(&evp2, 0, sizeof(struct sigevent)); 
    evp2.sigev_signo = SIGUSR1; //超时触发特定信号
    evp2.sigev_notify = SIGEV_SIGNAL; 

    timer_t timer2;
    if (timer_create(CLOCK_REALTIME, &evp2, &timer2) == -1) { 
        perror("fail to timer_create"); 
        exit(-1); 
    } 
 
    struct itimerspec it2; 
    it2.it_interval.tv_sec = 0; 
    it2.it_interval.tv_nsec = 999999999; 
    it2.it_value.tv_sec = 2; 
    it2.it_value.tv_nsec = 0; 
    if (timer_settime(timer2, 0, &it2, NULL) == -1) { 
        perror("fail to timer_settime(2)"); 
        exit(-1); 
    } 

    //注册信号回调函数
    struct sigaction act;
    memset(&act, 0, sizeof(act)); 
    act.sa_handler = sig_handler; 
    act.sa_flags = 0;

    // XXX int sigaddset(sigset_t *set, int signum);  //将signum指定的信号加入set信号集
    // XXX int sigemptyset(sigset_t *set);          //初始化信号集 
    sigemptyset(&act.sa_mask); 
 
    if (sigaction(SIGUSR1, &act, NULL) == -1) { 
        perror("fail to sigaction"); 
        exit(-1); 
    }
    //pause();
    int counter = 0;
    while (counter++ <= 15) {
        if(counter == 5) timer_delete(timer1);
        else if(counter == 10) timer_delete(timer2);
        sleep(1);
    }
    return 0;    
}
